/* Grab the current user */
var DevTK = {
	user: Titanium.JSON.parse( Titanium.API.get("authenticated") )
};

console.log( DevTK.user );

/* Build the irc configuration */
var irc = newIrcConnection( "irc.freenode.net", 6667, {
	callbacks: {
		unhandled: function(irc, msg) {
			addRawMsg( "<p>(Unhandled) " + msg.raw + "</p>" );
			switch( msg.command ) {
			case NUMERIC["RPL_NAMREPLY"]:
				add_channel_to_list( msg.params[2] );
				var users = msg.params[msg.trailing].split( " " );
				for(u=0;u<users.length;u++) {
					if( users[u].length ) {
						add_nick_to_list( users[u] );
						irc.add_nick( users[u], msg.params[2] );
					}
				}
				break;
			default:
				console.log( msg.raw );
			}
		},
		notice: function(irc, channel, nick, msg) {
			addRawMsg( build_message( channel, nick.nick, msg ) );
		},
		privmsg: function(irc, channel, nick, msg) {
			addRawMsg( build_message( channel, nick.nick, msg ) );
		},
		join: function(irc, channel, nick) {
			add_nick_to_list( nick.nick );
			var e = get_nick_selector( nick.nick );
			tooltip( "Just joined " + channel + "!", e, 4000 );
		},
		part: function(irc, channel, nick, reason) {
			if( !irc.has_nick( nick.nick ) ) {
				rem_nick_from_list( nick.nick );
				var e = get_channel_selector( channel );
				tooltip( nick.nick + " just left " + channel + "!", e, 4000 );
			} else {
				var e = get_nick_selector( nick.nick );
				tooltip( "Just left " + channel + "!", e, 4000 );
			}
		},
		nick: function(irc, oldnick, newnick) {
			rename_nick( oldnick, newnick );
		}
	}
});

var channel_index = 0;
var highlight_cache = [];

var sounds = {
	message: Titanium.Media.createSound( "app://wav/2788_1329133451.mp3" ),
	highlight: Titanium.Media.createSound( "app://wav/DingLing.mp3" ),
}

function add_nick_to_list( nick ) {
	if( !nick ) return;
	var stripped = irc.strip_nick_prefix( nick );
	if( $("li.irc-user a.user-reference[href='#user:" + stripped + "']").length > 0 ) {
		console.log( "Couldn't add " + stripped + " to nick list (already exists)." );
		return;
	}
	
	var colour = "hsl(" + Math.floor(Math.random()*360) + ", 80%, 40%)";
	var src = "<li class=\"irc-user\"><a class=\"user-reference\" href=\"#user:" + stripped + "\"><span class=\"user-colour\" style=\"background-color:" + colour + ";\"></span><span class=\"nick\">" + irc.strip_nick_prefix( nick ) + "</span></a></li>"
	if( $("li.irc-user").length == 0 ) {
		$("li.irc-user-head").after(src);
	} else {
		$("li.irc-user").last().after(src);
	}
}

function rename_nick( nick, newnick ) {
	if( !nick || !newnick ) return;
	var hits = $("li.irc-user a.user-reference[href='#user:" + irc.strip_nick_prefix( nick ) + "']");
	if( hits.length > 0 ) {
		$(hits).attr( "href", "#user:" + irc.strip_nick_prefix( newnick ) );
		$("span.nick", hits).html( irc.strip_nick_prefix( newnick ) );
	}
}

function get_nick_colour( nick ) {
	if( !nick ) return null;
	var hits = $("li.irc-user a.user-reference[href='#user:" + irc.strip_nick_prefix( nick ) + "']");
	if( hits.length > 0 ) {
		return $("span.user-colour", hits).css("background-color");
	}
	return null;
}

function get_nick_selector( nick ) {
	return "li.irc-user a.user-reference[href='#user:" + irc.strip_nick_prefix( nick ) + "']";
}

function rem_nick_from_list( nick ) {
	if( !nick ) return null;
	var hits = $("li.irc-user a.user-reference[href='#user:" + irc.strip_nick_prefix( nick ) + "']");
	if( hits.length > 0 ) {
		$(hits).remove();
	}
}

function add_channel_to_list( channel ) {
	if( !channel ) return;
	if( $("li.irc-channel a.channel-reference[href='#channel:" + channel + "']").length > 0 ) return;
	
	var src = "<li class=\"irc-channel\"><a class=\"channel-reference\" href=\"#channel:" + channel + "\">" + channel + "</a></li>"
	var element = $(src);
	if( $("li.irc-channel").length == 0 ) {
		$("li.irc-channel-head").after(element);
	} else {
		$("li.irc-channel:last").after(element);
	}
	$("li.irc-channel").removeClass("active");
	$(element).addClass("active");
	show_header( channel, irc.get_channel_topic( channel ) );
}

function get_active_channel() {
	var channel = $("li.irc-channel.active a.channel-reference").first();
	if( channel ) {
		var c = $(channel).html();
		console.log( "Channel=" + c );
		return c;
	}
	return null;
}

function rem_channel_from_list( channel ) {
	$("li.irc-channel.active a.channel-reference[href='#channel:" + channel + "']").remove();
}

function get_channel_selector( channel ) {
	return "li.irc-channel a.channel-reference[href='#channel:" + channel + "']";
}

function show_header( channel, topic ) {
	console.log( "Displaying topic for channel " + channel + " (" + topic + ")", topic );
	$("div.page-header h1 span.channel").html( channel );
	$("div.page-header h1 small.topic").html( topic );
	$("div.page-header").show();
	handle_resize( null );
}

function add_highlight( regex ) {
	if( !regex || regex[0] != "/" ) return false;
	if( $("li.irc-highlight a.highlight-reference[href='#regex:" + regex +"']").length > 0 ) return false;
	
	var parts = regex.substring(1).split("/");
	var pattern = parts[0];
	var modifiers = parts[1];
	try {
		var rx = new RegExp( pattern, modifiers );
		// If this doesn't throw an error, it must be a valid regular expression
		var src = "<li class=\"irc-highlight\"><a class=\"highlight-reference\" href=\"#regex:" + regex + "\" data-pattern=\"" + pattern + "\"  data-modifiers=\"" + modifiers + "\">" + regex + " &times;</a></li>"
		var node = $(src);
		$("a", node).click(function(e) { $(node).remove(); });
		$("li.irc-highlight-head").after(node);
	} catch( e ) { return false; /* Error */ }
	return true;
}

function get_highlights() {
	var list = [];
	$("li.irc-highlight a.highlight-reference").each(function(index, element){
		try {
			var regex = $(element).attr("href").split(":")[1];
			var parts = regex.substring(1).split("/");
			var pattern = parts[0];
			var modifiers = parts[1];
			var expression = new RegExp( pattern, modifiers );
			list.push( expression );
		} catch( e ) { /* Skip invalid regex */ }
	});
	return list;
}

function check_highlights( text ) {
	var h = get_highlights();
	if( h.length > 0 ) {
		for(i=0;i<h.length;i++){
			if( h[i].test( text ) ) return true;
		}
	}
	return false;
}

function replaceURLWithHTMLLinks(text) {
    var exp = /(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig;
    return text.replace(exp,"<a href='$1' class='link'>$1</a>");
}

function build_message( channel, nick, text ) {
	var colour = get_nick_colour( nick ) || "hsl(100, 13%, 93%);";
	if( text[0] == "\001" && text[text.length-1] == "\001" ) {
		var src = '<div class="chat-item well"><span>(' + channel + ')</span> <a href="#privmsg:' + (nick || "null") + '" class="nick"><span class=\"user-colour\" style=\"background-color:' + colour + ';\"></span> ' + (nick || "") + '</a> ' + text + '</div>'; 
		return src; 
	}
	var src = '<div class="well chat-item"><span>(' + channel + ')</span> <a href="#privmsg:' + (nick || "null") + '" class="nick"><span class=\"user-colour\" style=\"background-color:' + colour + ';\"></span> ' + (nick || "") + '</a> says:<br /><div class="quote">' + text + '</div></div>';
	return src;
}

function addRawMsg( ircmsg, highlight ) {
	var check = (highlight == window.undefined) ? true : highlight;
	source = replaceURLWithHTMLLinks( ircmsg );
	var html = $( source );
	var sound = "message";
	if( check_highlights( source ) && check ) {
		// report highlight
		$(html).addClass("alert");
		sound = "highlight";
	}
	$("div.chat-box").append(html).scrollTo(html,0);
	if( !sounds[sound].isPlaying() ) {
		sounds[sound].reload();
		sounds[sound].play();				
	}
}

function interpret_text( input ) {
	if( input[0] == "/" ) {
		var params = input.split(" ", 4);
		switch( params[0] ) {
		case "/join":
			irc.join( params[1] );
			break;
		case "/part":
			irc.part( params[1], params.slice(2).join(" ") );
			rem_channel_from_list( params[1] );
			break;
		case "/invite":
			irc.invite( params[1], params[2] );
			break;
		case "/nick":
			irc.nick( params[1] );
			break;
		case "/msg":
			irc.msg( params[1], params.slice(2).join(" ") );
			break;
		case "/me":
			var dest = get_active_channel();
			if( !dest ) {
				addRawMsg( "<p>Couldn't send message, not connected to a channel</p>" );
				return;
			}
			irc.msg( dest, "\001" + input + "\001" );
			addRawMsg( build_message( dest, irc.session.nick, "\001" + input + "\001" ), false );
			break;
		default:
			// report unsupported command
			addRawMsg( "<p>Command " + params[0] + " doesn't exist</p>" );
		}
		return;
	}
	var dest = get_active_channel();
	if( dest != null ) {
		irc.msg( dest, input );
		addRawMsg( build_message( dest, irc.session.nick, input ), false );
	} else {
		// Report error
	}
}

function handle_resize( event ) {
	var window = Titanium.UI.getCurrentWindow();
	//console.log( { window_height: window.getHeight(), window_width: window.getWidth() } );
	var extra = 0;
	if( $("div.page-header").is(":visible") ) extra = $("div.page-header").height() * 2.5; 
	var ch = window.getHeight() - (180 + extra);
	$("#conversations").css({
		"height": ch + "px !important",
	});
}

function tooltip( message, attachTo, ms ) {
	if( !message ) return;
	if( !attachTo ) return;
	var milliseconds = ms || 3000;
	
	$(attachTo).tooltip({
		selector: attachTo,
		trigger: 'manual',
		title: message
	});
	$(attachTo).tooltip('show');
	setTimeout(function(){
		$(attachTo).tooltip('hide');
	}, milliseconds);
}

$(document).ready(function(){
	Titanium.API.addEventListener( Titanium.RESIZED, handle_resize );
	
	$("a.devtk-user").html(DevTK.user.username);
	
	$("div.page-header").hide();
	
	handle_resize( null );
	
	$("textarea[name=irctext]").keydown(function(e){
		if( e.which == 13 ) {
			e.preventDefault();
			interpret_text( $(this).val() );
			$(this).val("");
			return false;
		} else if( e.which == 9 ) {
			e.preventDefault();
			var text = $(this).val();
			var last_space = text.lastIndexOf( " " );
			if( last_space >= 0 ) text = text.substring(last_space+1);
			var nicks = irc.get_user_list(null);
			var channels = irc.get_channel_list();
			var matches = nicks.concat( channels );
			var m = [];
			for(i=0;i<matches.length;i++) {
				if( text.length <= matches[i].length ) {
					var test = matches[i].substring(0, text.length)
					console.log( "comparing " + text + " =? " + test );
					if( text == test ) {
						console.log( "Tab-Completion/" + matches[i] + " matches your text" );
						m.push( matches[i] );
					}
				}
			}
			if( m.length == 1 ) {
				console.log( "Tab-Completion/Only one match, " + m[i] );
				$(this).val( $(this).val() + m[0].substring( text.length ) );
			} else if( m.length > 1 ) {
				console.log( "Possible matches:", m );
				var extra = "";
				var index = 0;
				while( index >= 0 ) {
					var letter = null;
					for(i=0;i<m.length;i++){
						if( m[i].length < index ) {
							index = -1;
							break;
						}
						if( letter == null ) letter = m[i][index];
						if( m[i][index] != letter ) {
							index = -1;
							break;
						}
					}
					if( index == -1 ) break;
					if( letter == null ) break;
					extra = extra + letter;
					index += 1;
				}
				if( ( extra.length > 0 ) && ( extra.length > text.length ) ) {
					$(this).val( $(this).val() + extra.substring( text.length ) );
				}
			}
		}
	});
	
	$("#new-highlight").parent("form").submit(function(e){
		e.preventDefault();
		var regex = $("#new-highlight").val();
		if( add_highlight( regex ) ) {
			$("#newhighlight").val("");
		} else {
			tooltip( "Invalid Regex", "#new-highlight", 2500 );
		}
		return false;
	});
	
	$("a.link").live("click",function(e){
		e.preventDefault();
		Titanium.Process.createProcess( [ "start", $(this).attr("href") ] ).launch();
		return false;
	});
	
	$("a.channel-reference").live("click", function(e){
		$("li.irc-channel").removeClass("active");
		$(this).parent("li").addClass("active");
		var cs = $(this).attr("href").split(":");
		$("div.page-header h1 span.channel").html( cs[1] );
		$("div.page-header h1 small.topic").html( irc.session.channels[ cs[1] ].topic || "" );
		$("div.page-header").show();
	});
	
	$("a.leave-channel[href='#action:part']").click(function(e){
		var chan = get_active_channel();
		irc.part( chan, "Leaving" );
		rem_channel_from_list( chan );
	});
});

irc.connect();
irc.pass( "youeyechat" );
irc.user( Titanium.Platform.getUsername(), "Alex" );
irc.nick( "Alex_DTK" );
irc.join( "#devtk" );
